home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 134_01 / cprofil2.csm < prev    next >
Text File  |  1985-08-19  |  12KB  |  511 lines

  1. ;    BDS `C' Profiler - Assembly Language portion
  2.  
  3. ;    Copyright (c) 1983 by Kevin B. Kenny.
  4. ;    Released to the BDS `C' Users' Group for non-commercial distribution.
  5.  
  6. ;    This file contains the assembly-language functions needed by the BDS
  7. ; `C' profiler program.
  8.  
  9. ;    Functions included:
  10.  
  11. ;    superv    chain    nexecl
  12.  
  13.     MACLIB    "BDS"
  14.  
  15. SECSIZ    EQU    128            ; Disk sector size in CP/M
  16.  
  17. ; SUPERV -- Run-time supervisor for profiler
  18.  
  19. ;    The folowing function must *NOT* be called from the 'C' program.  It
  20. ; contains the code for the profiler which is loaded into high memory while
  21. ; the profiled program is executing.  The code intercepts the RST 6 operations
  22. ; that delineate the source statements, and accumulates the totals.  Upon any
  23. ; attempt to warm-boot CP/M, the supervisor reloads CPROFILE and transfers to
  24. ; it to do the analysis and print the results.
  25.  
  26.     FUNCTION     superv
  27.  
  28. ;    The following locations are fixed offsets from the beginning of SUPERV,
  29. ; used for communication with CPROFILE itself.  Their order and size must not
  30. ; be changed without changing CPROFILE as well.
  31.  
  32. START    jmp    $-$            ; Imitation BDOS entry to mark top of
  33.                     ; available memory.  Transfers to real
  34.                     ; BDOS for processing.
  35.  
  36.     db    'cprofile', 0        ; Signature, used by CPROFILE to detect
  37.                     ; that he's been reloaded.
  38.  
  39.     jmp    preinit            ; Transfer to preliminary init code.
  40.  
  41.     jmp    fakeboot        ; Transfer to artificial warmboot
  42.                     ; routine.
  43.  
  44.     dw    suptop            ; Size of the supervisor
  45.  
  46.     dw    table            ; Pointer to first profile table entry.
  47. tbnext:
  48.     dw    table            ; Pointer to next available slot for
  49.                     ; profile table entry.
  50.  
  51. realboot:
  52.     dw    $-$            ; BIOS warm-boot entry before CPROFILE
  53.                     ; was invoked.
  54.  
  55. cmdline:
  56.     ds    128            ; CPROFILE command tail, used to reload
  57.                     ; CPROFILE.
  58.  
  59. ;    Come here on preliminary initialization after reading the target
  60. ; program into the lower TPA.  Dummy up a CCP stack pointer, clobber the
  61. ; "khack" portion of C.CCC initialization, and go re-initialize C.CCC for
  62. ; the target program.
  63.  
  64. preinit:
  65.     lxi    sp, preinit        ; Fake a stack pointer for target
  66.     mvi    a, 0C9h    ; (RET)        ; Save a return instruction in "khack"
  67.     sta    khack
  68.     mvi    a, 0C3h    ; (JMP)        ; Set up the RST 6 vector for profiling
  69.     sta    00030h
  70.     lxi    h, rst6ent
  71.     shld    00031h
  72.  
  73.     mvi    c, pstrng        ; Print message that we got here.
  74.     lxi    d, entrmsg
  75.     call    start
  76.  
  77.     call    tpa            ; Go enter the user program.
  78.  
  79.     jmp    fakeboot        ; Reload profiler when program finishes
  80.  
  81. ;    Come here on a RST 6 instruction within the target program.  Accumulate
  82. ; the profile data.
  83.  
  84. rst6ent:
  85.     push    h            ; Save all registers
  86.     push    d
  87.     push    b
  88.     push    psw
  89.  
  90.     lxi    h, 8            ; Increment return address around
  91.     dad    sp            ; line and statement information.
  92.     mov    c,m
  93.     inx    h
  94.     mov    b,m
  95.     inx    b
  96.     inx    b
  97.     mov    m,b
  98.     dcx    h
  99.     mov    m,c
  100.     dcx    h
  101.     dcx    b
  102.     dcx    b            ; Get original PC back
  103.  
  104.     lhld    tbnext
  105.     xchg                ; Get start and end of profile table
  106.     lxi    h, table
  107.  
  108. ploop:    mov    a, d            ; If at end of table, go to NOTFND
  109.     cmp    h
  110.     jnz    notdone
  111.     mov    a,e
  112.     cmp    l
  113.     jz    notfnd
  114.  
  115. notdone:
  116.     mov    a,c            ; If the PC in table doesn't match ours
  117.     cmp    m            ; go to NOTHERE(2) to advance to next
  118.     jnz    nothere         ; table entry.
  119.     inx    h
  120.     mov    a,b
  121.     cmp    m
  122.     jnz    nothere2
  123.  
  124.     lxi    b,4            ; Point HL to least significant byte of
  125.     dad    b            ; execution count
  126.  
  127.     mov    a,m
  128.     adi    1            ; Increment trip count
  129.     mov    m,a
  130.     dcx    h
  131.     mov    a,m
  132.     aci    0
  133.     mov    m,a
  134.     dcx    h
  135.     mov    a,m
  136.     aci    0
  137.     mov    m,a
  138.     dcx    h
  139.     mov    a,m
  140.     aci    0
  141.     mov    m,a
  142.  
  143.     jmp    finis            ; Done with this RST 6
  144.  
  145. nothere:
  146.     inx    h            ; Advance to next table entry
  147. nothere2:
  148.     inx    h
  149.     inx    h
  150.     inx    h
  151.     inx    h
  152.     inx    h
  153.     jmp    ploop
  154.  
  155. notfnd:
  156.     lda    start+1
  157.     sui    6
  158.     sub    l            ; Entry not found in table.  Make sure
  159.     lda    start+2            ; there's space for it.
  160.     sbb    h
  161.     jnc    addent
  162.  
  163.     mvi    c,pstrng        ; There isn't; complain and abort.
  164.     lxi    d,fullmsg
  165.     call    start
  166.     jmp    base
  167.  
  168. addent:
  169.     mov    m,c            ; Add an entry to table; first the PC,
  170.     inx    h
  171.     mov    m,b
  172.     inx    h
  173.     xra    a            ; then a count of 1.
  174.     mov    m,a
  175.     inx    h
  176.     mov    m,a
  177.     inx    h
  178.     mov    m,a
  179.     inx    h
  180.     inr    a
  181.     mov    m,a
  182.     inx    h
  183.  
  184.     shld    tbnext            ; Advance table end.
  185.  
  186. finis:
  187.     pop    psw
  188.     pop    b
  189.     pop    d
  190.     pop    h
  191.     ret                ; Return to target program
  192.  
  193. ;    Come here on a call to BIOS warmboot function or BDOS function 0.
  194. ; Reload CPROFILE in the lower TPA, and perform the analysis of the profile
  195. ; data gathered up in the TABLE area.
  196.  
  197. fakeboot:
  198.     lhld    realboot        ; Reset BIOS warm-boot transfer to
  199.     xchg                ; its original value.
  200.     lhld    base+1
  201.     inx    h
  202.     mov    m,e
  203.     inx    h
  204.     mov    m,d
  205.  
  206.     mvi    c, pstrng        ; Print a message to announce what's
  207.     lxi    d, rlodmsg        ; happening
  208.     call    bdos
  209.  
  210.     lxi    d, tbuff        ; Move command tail back in place
  211.     lxi    h, cmdline
  212.     mvi    c, 128
  213. mtail:    mov    a, m
  214.     stax    d
  215.     inx    h
  216.     inx    d
  217.     dcr    c
  218.     jnz    mtail
  219.  
  220.     mvi    c, openc        ; Re-open CPROFILE.COM
  221.     lxi    d, cprfcb
  222.     call    bdos
  223.     inr    a
  224.     jz    openerr
  225.     xra    a
  226.     sta    cprfcb+32        ; Zero current record index.
  227.  
  228. rloop:    lhld    loadorg            ; Get present loading origin
  229.     xchg
  230.     lxi    h, secsiz        ; Bump it by a sector for next time
  231.     dad    d
  232.     shld    loadorg
  233.     mvi    c, sdma            ; Set DMA pointer to loading origin
  234.     call    bdos
  235.  
  236.     mvi    c, reads        ; Read in a sector of CPROFILE.COM
  237.     lxi    d, cprfcb
  238.     call    bdos
  239.     ora    a
  240.     jz    rloop            ; Continue reading until EOF
  241.  
  242.     mvi    c, closec        ; Close CPROFILE.COM
  243.     lxi    d, cprfcb
  244.     call    bdos
  245.  
  246.     mvi    c, sdma            ; Reset default DMA address
  247.     lxi    d, tbuff
  248.     call    bdos
  249.  
  250.     jmp    tpa            ; Go enter reloaded copy of CPROFILE
  251.  
  252. openerr:                ; Couldn't reopen CPROFILE.COM
  253.     mvi    c, pstrng
  254.     lxi    d, opermsg
  255.     call    bdos
  256.     jmp    base
  257.  
  258. entrmsg:
  259.     db    '<<< Executing target program. >>>', CR, LF, '$'
  260. fullmsg:
  261.     db    CR, LF, '<<< Profile table is full.  Abandoning program. >>>'
  262.     db    '$'
  263. rlodmsg:
  264.     db    CR, LF, '<<< Reloading CPROFILE. >>>', CR, LF, '$'
  265. opermsg:
  266.     db    'Can''t open CPROFILE.COM; CPROFILE abandoned.$'
  267.  
  268. loadorg:
  269.     dw    tpa            ; Loading origin of CPROFILE
  270. cprfcb:
  271.     db    0, 'CPROFILE', 'COM', 0, 0, 0, 0
  272.     dw    0, 0, 0, 0, 0, 0, 0, 0    ; FCB for CPROFILE.COM
  273.     db    0, 0, 0, 0
  274.  
  275. table:                                ; Profile table starts here.
  276.  
  277. suptop:                    ; Top of the supervisor
  278.  
  279.     ENDFUNC        superv
  280.  
  281. ; CHAIN
  282.  
  283. ;        The following function is used to chain to the program being
  284. ;    analyzed.  It takes the following calling sequence:
  285.  
  286. ;        chain (argc, argv, entry);
  287.  
  288. ;    where argc and argv are the usual command parameters (argv [0] is the
  289. ;    name of the .COM file to load), and entry is the entry address of the
  290. ;    loaded program.  Entry would be 0x100 under normal circumstances, but
  291. ;    the CPROFILE run-time supervisor has a few unusual entry tasks to do.
  292.  
  293.     FUNCTION     chain
  294.  
  295.     EXTERNAL    nexecl
  296.  
  297.     call    arghak            ; Get the arguments
  298.     push    b
  299.  
  300.     lhld    arg3
  301.     push    h            ; Push the entry point address
  302.     lxi    h,0
  303.     push    h            ; Push the argv fence
  304.     lhld    arg1
  305.     xchg                ; Get DE = arg count, HL -> argv end
  306.     lhld    arg2
  307.     dad    d
  308.     dad    d
  309.  
  310. loop:    dcx    h
  311.     mov    a,m
  312.     dcx    h            ; Place an argument on stack
  313.     push    h
  314.     mov    l,m
  315.     mov    h,a
  316.     xthl
  317.  
  318.     dcx    d            ; Count down arguments until finished
  319.     mov    a, d
  320.     ora    e
  321.     jnz    loop
  322.  
  323. done:    call    nexecl            ; Go call NExecl to load the program
  324.     jmp    base            ; NEXECL return is a disaster.
  325.  
  326.     ENDFUNC    
  327.  
  328. ; NEXECL
  329.  
  330. ;        Derived from the EXECL function in the BDS `C' system library
  331. ;    (DEFF2C.CSM) copyright (c) 1983 by Leor Zolman.  Used by permission.
  332.  
  333. ;        This function is identical to the EXECL function in the BDS 'C'
  334. ;    system library with the single exception that it accepts an additional
  335. ;    argument following the list of command line arguments and the zero
  336. ;    terminator.  This argument is the address of a preinitialization entry
  337. ;    point to which the loader will transfer instead of entering the TPA
  338. ;    directly at 0x0100.
  339.  
  340.     FUNCTION    nexecl
  341.  
  342.     call    arghak
  343.     push    b
  344.     lhld    arg1                                              
  345.     xchg
  346.     lxi    h,-60    ;compute &nfcb for use here
  347.     dad    sp
  348.     push    h    ; save for much later (will pop    into BC)
  349.       push    h    ;make a few copies for local use below
  350.     push    h
  351.     call    setfcu    ;set up COM file for execl-ing
  352.     lda    usrnum
  353.     call    setusr    ;set destination user area
  354.     pop    h    ;get new fcb addr
  355.     lxi    b,9    ;set extension to COM
  356.     dad    b
  357.     mvi    m,'C'
  358.     inx    h
  359.     mvi    m,'O'
  360.     inx    h
  361.     mvi    m,'M'
  362.     pop    d    ;get new fcb addr again
  363.     mvi    c,openc    ;open the fi